package com.linln.admin.pcs.service;

import com.alibaba.fastjson.JSONArray;
import com.alibaba.fastjson.JSONObject;
import com.linln.admin.config.IDCardEncryptor;
import com.linln.admin.config.ToInterFaceToolConfig;
import com.linln.admin.pcs.api.WeChatController;
import com.linln.admin.rsa.ToInterfaceTool;
import com.linln.admin.util.ToolUtils;
import com.linln.common.data.QuerySpec;
import com.linln.common.utils.DateUtils;
import com.linln.modules.system.domain.*;
import com.linln.modules.system.repository.DepRepository;
import com.linln.modules.system.repository.PatientAdmissionRepository;
import com.linln.modules.system.repository.PatientRepository;
import org.apache.commons.lang3.ObjectUtils;
import org.apache.commons.lang3.StringUtils;
import org.apache.ibatis.annotations.ResultType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.AsyncResult;
import org.springframework.stereotype.Service;

import java.nio.charset.StandardCharsets;
import java.util.*;
import java.util.concurrent.CompletableFuture;
import java.util.concurrent.Future;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;

@Service
public class RsaService {

    private final static Logger logger = LoggerFactory.getLogger(RsaService.class);
    @Autowired
    private PatientAdmissionRepository patientAdmissionRepository;

    @Autowired
    private ToInterFaceToolConfig toInterFaceToolConfig;

    @Autowired
    private PatientRepository patientRepository;

    @Autowired
    private DepRepository depRepository;

    @Value("${wx.appId}")
    private String APPID;

    @Value("${wx.appSecret}")
    private String APP_KEY;

    @Value("${wx.appOpenid}")
    private String APPOPENID;

    @Value("${wx.appOpendKey}")
    private String APP_OPEN_KEY;

    //根据身份证获取患者档案信息
    private String GET_PATIENT_INFO_BY_CARDNO = "https://yxxyy.msunhis.com:1443/msun-middle-aggregate-patient/v1/patInfosFind";

    //患者住院基本信息
    private String PATIEN_ADMINSSTION = "https://yxxyy.msunhis.com:1443/msun-middle-aggregate-hsz/v1/patients";

    //根据openid获取患者信息
    private  String GET_OPENID = "https://xxb.o2o.bailingjk.net/bluser/api/v1/getPatientListOtherByOpenId";

    //病区基本信息接口
    private String DEPTS_INFO = "https://yxxyy.msunhis.com:1443/msun-middle-base-common/v1/wards";

    //居民类别信息接口
    private String PATS_INFO = "https://yxxyy.msunhis.com:1443/msun-middle-base-common/v1/dict/pat-types";


    public JSONArray getPatInfo() throws Exception {
        Map<String, Object> getParam = new HashMap<>();
        ToInterfaceTool tool = toInterFaceToolConfig.toInterfaceTool();
        String body = tool.toGet(PATS_INFO, getParam);
        logger.error("居民类别信息body："+body);
        if (StringUtils.isNotEmpty(body)){
            JSONObject jsonObject = JSONObject.parseObject(body);
            if (ObjectUtils.isNotEmpty(jsonObject)){
                boolean success = jsonObject.getBoolean("success");
                if (success){
                    JSONArray data = jsonObject.getJSONArray("data");
                    logger.error("居民类别信息："+data);
                    return data;
                }
            }
        }
        return null;
    }


    /**
     * 获取病区信息
     * @return
     * @throws Exception
     */
    public List<Dep> getDepIdList(){
        QuerySpec spec = QuerySpec.matching();
        spec.withMatcherValue("status", QuerySpec.EQUAL, "1");
        List<Dep> depts = depRepository.findAll(QuerySpec.of(spec));
        try {
            Map<String, Object> getParam = new HashMap<>();
            getParam.put("invalidFlag","0");
            ToInterfaceTool tool = toInterFaceToolConfig.toInterfaceTool();
            String body = tool.toGet(DEPTS_INFO, getParam);

            if (depts.size()==0){
                if (StringUtils.isNotEmpty(body)){
                    JSONObject jsonObject = JSONObject.parseObject(body);
                    if (ObjectUtils.isNotEmpty(jsonObject)){
                        boolean success = jsonObject.getBoolean("success");
                        if (success){
                            JSONArray data = jsonObject.getJSONArray("data");
                            if (ObjectUtils.isNotEmpty(data)){
                                for (int i = 0; i < data.size(); i++) {
                                    JSONObject jsonObject1 = data.getJSONObject(i);
                                    Dep dep = new Dep();
                                    dep.setDeptId(jsonObject1.getString("wardId"));
                                    dep.setName(jsonObject1.getString("wardName"));
                                    dep.setCategoryId(jsonObject1.getString("wardCode"));
                                    depts.add(dep);
                                }
                                depRepository.saveAll(depts);
                            }
                        }
                    }
                }
            }
        } catch (Exception e) {
            return depts;
        }
        return depts;
    }

    /**
     *根据openid获取患者信息
     * @param openId
     * @return
     * @throws Exception
     */
    public List<PatientParam> getPatientByOpenid(String openId){
        logger.error("根据openid获取患者信息："+openId);
        List<PatientParam> patientParams = new ArrayList<>();
        try {
            return CompletableFuture.supplyAsync(() -> {
                // 1. 加密敏感参数
                String encryptedOpenId = null;
                try {
                    encryptedOpenId = ToolUtils.aesEncrypt(openId, APP_OPEN_KEY);
                    // 2. 构建请求体
                    String requestBody = String.format("{\"openId\":\"%s\"}", encryptedOpenId);
                    String base64Body = Base64.getEncoder().encodeToString(requestBody.getBytes(StandardCharsets.UTF_8));
                    // 3. 生成时间戳
                    long ts = System.currentTimeMillis();

                    // 4. 构建请求参数
                    Map<String, String> params = new LinkedHashMap<>();
                    params.put("appId", APPOPENID);
                    params.put("ts", String.valueOf(ts));
                    params.put("base64JsonBody", base64Body);
                    params.put("appKey", ToolUtils.aesEncrypt(APP_OPEN_KEY, APP_OPEN_KEY));
                    logger.error("根据openid获取患者信息参数"+params);
                    // 5. 生成签名
                    String sign = ToolUtils.generateMD5Signature(params);

                    // 6. 构建最终请求URL
                    String finalUrl = ToolUtils.buildFinalUrl(GET_OPENID,APPOPENID,ts, sign);
                    String s = ToolUtils.sendPostRequest(finalUrl, requestBody);

                    if (StringUtils.isNotEmpty(s)){
                        JSONObject jsonObject = JSONObject.parseObject(s);
                        logger.error("根据openid获取患者信息结果:"+jsonObject);
                        if (ObjectUtils.isNotEmpty(jsonObject)){
                            boolean ss = jsonObject.getBoolean("success");
                            logger.error("根据openid获取患者信息标志:"+ss);
                            if (ss){
                                JSONArray data = jsonObject.getJSONArray("data");
                                if (ObjectUtils.isNotEmpty(data)){
                                    for (int i = 0; i < data.size(); i++) {
                                        JSONObject jsonObject1 = data.getJSONObject(i);
                                        PatientParam patientParam = new PatientParam();
                                        String patientName = IDCardEncryptor.aesDecrypt(jsonObject1.getString("patientName"));
                                        String cardNo = IDCardEncryptor.aesDecrypt(jsonObject1.getString("cardNo"));
                                        String phoneNo = IDCardEncryptor.aesDecrypt(jsonObject1.getString("phoneNo"));
                                        String sex = IDCardEncryptor.aesDecrypt(jsonObject1.getString("sex"));
                                        String birthdate = IDCardEncryptor.aesDecrypt(jsonObject1.getString("birthdate"));
                                        String address = IDCardEncryptor.aesDecrypt(jsonObject1.getString("address"));


                                        patientParam.setPatientName(patientName);
                                        patientParam.setCardNo(cardNo);
                                        patientParam.setPhoneNo(phoneNo);
                                        patientParam.setSex(sex);
                                        patientParam.setBirthdate(birthdate);
                                        patientParam.setAddress(address);
                                        patientParam.setOpenId(openId);
                                        patientParams.add(patientParam);
                                    }
                                }
                            }
                        }
                    }
                } catch (Exception e) {
                    logger.error("根据openid获取患者信息报错1:"+e.getMessage());
                    return patientParams;
                }
                return patientParams;
            }).get(5, TimeUnit.SECONDS); // 5秒超时
        } catch (TimeoutException e) {
            logger.error("根据openid获取患者信息报错2:"+e.getMessage());
            return patientParams;
        } catch (Exception e) {
            logger.error("根据openid获取患者信息报错3:"+e.getMessage());
            return patientParams;
        }
    }



    /**
     * 根据身份证获取患者档案信息
     * @throws Exception
     */
    /*public Patient getPatientInfoByCardno(String cardNo,String name) throws Exception {
        logger.error("根据身份证获取患者档案信息:"+cardNo+",姓名:"+name);
        QuerySpec querySpec = QuerySpec.matching();
        String s = IDCardEncryptor.aesEncrypt(cardNo);
        querySpec.withMatcherValue("cardNo", QuerySpec.EQUAL,s);
        List<Patient> patients = patientRepository.findAll(QuerySpec.of(querySpec));
        if (patients.size()>0){
            return patients.get(0);
        }else{
            try {
                return CompletableFuture.supplyAsync(() -> {
                    try {
                        Map<String, Object> getParam = new HashMap<>();
                        getParam.put("type", "2");
                        getParam.put("patName", name);
                        getParam.put("idCardType", 0);
                        getParam.put("idCardNo", cardNo);
                        logger.error("根据身份证获取患者档案信息参数:"+getParam);
                        ToInterfaceTool tool = toInterFaceToolConfig.toInterfaceTool();
                        String info = tool.toGet(GET_PATIENT_INFO_BY_CARDNO, getParam);
                        if (StringUtils.isNotEmpty(info)){
                            JSONObject jsonObject = JSONObject.parseObject(info);
                            logger.error("根据身份证获取患者档案信息详情:"+jsonObject);
                            if (ObjectUtils.isNotEmpty(jsonObject)){
                                if (jsonObject.containsKey("success")) {
                                    boolean ss = jsonObject.getBoolean("success");
                                    logger.error("根据身份证获取患者档案信息参数success:"+ss);
                                    if (ss){
                                        if (jsonObject.containsKey("data")) {
                                            JSONObject data = jsonObject.getJSONObject("data");
                                            logger.error("根据身份证获取患者档案信息详情:"+data);
                                            Patient patient = new Patient();
                                            patient.setPatId(data.getString("patId"));
                                            patient.setName(data.getString("patName"));
                                            String sex = data.getString("sex");
                                            if (StringUtils.isNotEmpty(sex)){
                                                if (sex.equals("男")){
                                                    patient.setSex((byte) 1);
                                                }else if (sex.equals("女")){
                                                    patient.setSex((byte) 2);
                                                }
                                            }
                                            patient.setPhone(data.getString("phone"));
                                            patient.setBirthDate(data.getString("birthday"));
                                            patient.setCardNo(data.getString("idCardNo"));
                                            patient.setEthnicity(data.getString("nationName"));
                                            patient.setHomeAddress(data.getString("addr"));
                                            patient.setHukouLocation(data.getString("addr"));
                                            int isWl = 0;
                                            if (null!=data.getString("patTypeId")){
                                                String patTypeId = data.getString("patTypeId");
                                                if (patTypeId.equals("7396862388163314439")){
                                                    isWl = 1;
                                                }
                                            }
                                            patient.setIsWl(isWl);
                                            patient.setPatTypeId(data.getString("patTypeId"));
                                            patient.setPatTypeName(data.getString("patTypeName"));
                                            patient.setProfessionName(data.getString("professionName"));
                                            patient.setCountry(data.getInteger("country"));
                                            patient.setCountryName(data.getString("countryName"));
                                            patient.setProvince(data.getInteger("province"));
                                            patient.setProvinceName(data.getString("provinceName"));
                                            patient.setCity(data.getInteger("city"));
                                            patient.setCityName(data.getString("cityName"));
                                            patient.setTown(data.getInteger("town"));
                                            patient.setTownName(data.getString("townName"));
                                            patient.setInfo(IDCardEncryptor.aesEncrypt(data.toJSONString()));
                                            return patient;
                                        }
                                    }
                                }
                            }
                        }
                    }catch (Exception e){
                        logger.error("根据身份证获取患者档案信息报错1:"+e.getMessage());
                        return null;
                    }
                    return null;
                }).get(5, TimeUnit.SECONDS); // 5秒超时
            } catch (TimeoutException e) {
                logger.error("根据身份证获取患者档案信息报错2:"+e.getMessage());
                return null;
            } catch (Exception e) {
                logger.error("根据身份证获取患者档案信息报错3:"+e.getMessage());
                return null;
            }
        }
    }*/


    public Patient getPatientInfoByCardno(String cardNo,String name) throws Exception {
        logger.error("根据身份证获取患者档案信息:"+cardNo+",姓名:"+name);
        try {
            return CompletableFuture.supplyAsync(() -> {
                try {
                    Map<String, Object> getParam = new HashMap<>();
                    getParam.put("type", "2");
                    getParam.put("patName", name);
                    getParam.put("idCardType", 0);
                    getParam.put("idCardNo", cardNo);
                    logger.error("根据身份证获取患者档案信息参数:"+getParam);
                    ToInterfaceTool tool = toInterFaceToolConfig.toInterfaceTool();
                    String info = tool.toGet(GET_PATIENT_INFO_BY_CARDNO, getParam);
                    if (StringUtils.isNotEmpty(info)){
                        JSONObject jsonObject = JSONObject.parseObject(info);
                        logger.error("根据身份证获取患者档案实体详情:"+jsonObject);
                        if (ObjectUtils.isNotEmpty(jsonObject)){
                            if (jsonObject.containsKey("success")) {
                                boolean ss = jsonObject.getBoolean("success");
                                logger.error("根据身份证获取患者档案信息参数success:"+ss);
                                if (ss){
                                    if (jsonObject.containsKey("data")) {
                                        JSONObject data = jsonObject.getJSONObject("data");
                                        logger.error("根据身份证获取患者档案信息详情:"+data);
                                        Patient patient = new Patient();
                                        patient.setPatId(data.getString("patId"));
                                        patient.setName(data.getString("patName"));
                                        String sex = data.getString("sex");
                                        if (StringUtils.isNotEmpty(sex)){
                                            if (sex.equals("男")){
                                                patient.setSex((byte) 1);
                                            }else if (sex.equals("女")){
                                                patient.setSex((byte) 2);
                                            }
                                        }
                                        patient.setPhone(data.getString("phone"));
                                        patient.setBirthDate(data.getString("birthday"));
                                        patient.setCardNo(data.getString("idCardNo"));
                                        patient.setEthnicity(data.getString("nationName"));
                                        patient.setHomeAddress(data.getString("addr"));
                                        patient.setHukouLocation(data.getString("addr"));
                                        int isWl = 0;
                                        if (null!=data.getString("patTypeId")){
                                            String patTypeId = data.getString("patTypeId");
                                            if (patTypeId.equals("7396862388163314439")){
                                                isWl = 1;
                                            }
                                        }
                                        patient.setIsWl(isWl);
                                        patient.setPatTypeId(data.getString("patTypeId"));
                                        patient.setPatTypeName(data.getString("patTypeName"));
                                        patient.setProfessionName(data.getString("professionName"));
                                        patient.setCountry(data.getInteger("country"));
                                        patient.setCountryName(data.getString("countryName"));
                                        patient.setProvince(data.getInteger("province"));
                                        patient.setProvinceName(data.getString("provinceName"));
                                        patient.setCity(data.getInteger("city"));
                                        patient.setCityName(data.getString("cityName"));
                                        patient.setTown(data.getInteger("town"));
                                        patient.setTownName(data.getString("townName"));
                                        patient.setInfo(IDCardEncryptor.aesEncrypt(data.toJSONString()));
                                        return patient;
                                    }
                                }
                            }
                        }
                    }
                }catch (Exception e){
                    logger.error("根据身份证获取患者档案信息报错1:"+e.getMessage());
                    return null;
                }
                return null;
            }).get(5, TimeUnit.SECONDS); // 5秒超时
        } catch (TimeoutException e) {
            logger.error("根据身份证获取患者档案信息报错2:"+e.getMessage());
            return null;
        } catch (Exception e) {
            logger.error("根据身份证获取患者档案信息报错3:"+e.getMessage());
            return null;
        }
    }

    /**
     * 根据患者住院号获取患者住院信息(定时任务用)
     * @throws Exception
     */
    public String getPatientCyAdmissionInfo(PatientAdmission patientAdmission){
        Map<String, Object> getParam = new HashMap<>();
        if (StringUtils.isNotEmpty(patientAdmission.getPatInHosCode())){
            try {
                return CompletableFuture.supplyAsync(() -> {
                    try {
                        String body = "";
                        getParam.put("patInHosCode", Integer.parseInt(patientAdmission.getPatInHosCode()));//患者住院号
                        getParam.put("patId", patientAdmission.getPatId());//患者ID
                        getParam.put("patInHosId", patientAdmission.getPatInHosId());//患者住院ID
                        logger.error("定时患者住院信息参数:"+getParam);
                        ToInterfaceTool tool = toInterFaceToolConfig.toInterfaceTool();
                        body = tool.toGet(PATIEN_ADMINSSTION, getParam);
                        logger.error("定时患者住院信息结果详情:"+body);
                        return body;
                    }catch (Exception e){
                        logger.error("定时患者住院信息参数报错1:"+e.getMessage());
                        return "";
                    }
                }).get(5, TimeUnit.SECONDS); // 5秒超时
            } catch (TimeoutException e) {
                logger.error("定时患者住院信息参数报错2:"+e.getMessage());
                return "";
            } catch (Exception e) {
                logger.error("定时患者住院信息参数报错3:"+e.getMessage());
                return "";
            }
        }else{
            logger.error("定时患者住院信息:"+patientAdmission);
            return "";
        }
    }

    /**
     * 获取患者住院信息
     * @return
     * @throws Exception
     */
    public PatientAdmission getPatientAdmissionInfo(String patientId,String patId,String phone){
        logger.error("获取患者住院信息:"+patientId);
        //查询患者是否已经住院
        QuerySpec querySpec = QuerySpec.matching();
        querySpec.withMatcherValue("patientId", QuerySpec.EQUAL,patientId)
                .withMatcherValue("admissionStatus",QuerySpec.EQUAL,"1")
                .withMatcherValue("status",QuerySpec.EQUAL,"1");
        List<PatientAdmission> admissionList = patientAdmissionRepository.findAll(QuerySpec.of(querySpec));
        if (admissionList.size()>0){
            return admissionList.get(0);
        }else{
            try {
                return CompletableFuture.supplyAsync(() -> {
                    try {
                        Map<String, Object> getParam = new HashMap<>();
                        getParam.put("patId", patId);//患者ID
                        getParam.put("patStatus", 1);//住院状态 1在院 2出院
                        logger.error("获取患者住院信息参数:"+getParam);
                        ToInterfaceTool tool = toInterFaceToolConfig.toInterfaceTool();
                        String body = tool.toGet(PATIEN_ADMINSSTION, getParam);
                        if (StringUtils.isNotEmpty(body)){
                            JSONObject jsonObject = JSONObject.parseObject(body);
                            logger.error("获取患者住院信息结果:"+jsonObject);
                            if (ObjectUtils.isNotEmpty(jsonObject)){
                                if (jsonObject.containsKey("success")) {
                                    boolean ss = jsonObject.getBoolean("success");
                                    logger.error("获取患者住院信息标志:"+ss);
                                    if (ss){
                                        if (jsonObject.containsKey("data")) {
                                            PatientAdmission patientAdmission = new PatientAdmission();
                                            JSONArray ary = jsonObject.getJSONArray("data");
                                            logger.error("获取患者住院信息结果详情:"+ary);
                                            if (ary.size()>0){
                                                Object obj = ary.get(0);
                                                JSONObject data = (JSONObject) obj;
                                                patientAdmission.setPatientId(Long.valueOf(patientId));
                                                patientAdmission.setAdmissionStatus((byte) 1);

                                                patientAdmission.setPatId(data.getString("patId"));
                                                patientAdmission.setName(data.getString("patName"));
                                                patientAdmission.setBedNo(data.getString("bedShowNo"));
                                                patientAdmission.setDepId(data.getString("patWardId"));
                                                patientAdmission.setDepName(data.getString("patWardName"));
                                                patientAdmission.setAdmissionTime(data.getString("patInTime"));
                                                patientAdmission.setOrderNo(data.getString("patInHosCode"));
                                                patientAdmission.setPatInHosId(data.getString("patInHosId"));
                                                patientAdmission.setPatInHosCode(data.getString("patInHosCode"));
                                                patientAdmission.setPhone(phone);
                                                patientAdmission.setInfo(IDCardEncryptor.aesEncrypt(data.toJSONString()));
                                                patientAdmissionRepository.save(patientAdmission);
                                                return patientAdmission;
                                            }
                                        }
                                    }
                                }
                            }
                        }
                    }catch (Exception e){
                        logger.error("获取患者住院信息报错1:"+e.getMessage());
                        return null;
                    }
                    return null;
                }).get(5, TimeUnit.SECONDS); // 5秒超时
            } catch (TimeoutException e) {
                logger.error("获取患者住院信息报错2:"+e.getMessage());
                return null;
            } catch (Exception e) {
                logger.error("获取患者住院信息报错3:"+e.getMessage());
                return null;
            }

        }

    }

}
